之前我們建了一個專案,但是完全沒有從後端帶任何資料到前端的頁面,那到底要如何將資料帶到前端呢?在MVC 中主要有兩種方式,一種是用ViewBag或ViewData等物件傳遞,另外一種方式是使用Model,那我們今天先看一下第一種方式。
首先這類的方式有三種物件
之前有看過一篇文章,有提到ViewData的一些問題,還是建議使用ViewBag就好了,雖然我忘記是什麼問題,不過基本上我幾乎沒有使用過ViewData,所以這部分就跳過,我這次參考的文章也沒有提到ViewData的實作,在最後會附上這次的參考網頁,雖然大部分參考的內容都寫在上面了,下面的大多是自己的想法跟經驗,不過這一篇有提到一個很重要的觀念,記在下面:
ViewData和ViewBag內的資料都是透過Key/Value的方法來存取,但請注意在同個頁面中他們的key值還是不能重複,否則將會出現問題,後面的值會把前面的值蓋過去,導致讀出來的資料是有問題的。
網站上也有簡單的範例說明,有興趣的話可以去看。
我幾乎只會用到ViewBag來傳遞物件,不會用到ViewData及TempData,所以今天的例子也只用到ViewBag而已,ViewBag可以傳遞的物件很多,包括單一變數,一個Model,甚至Model的List,或者DataTable之類的物件都可以,我還沒有遇過ViewBag無法傳遞的物件。
在這個例子我們將之前的專案清空,以最原始的風貌來呈現,由於這30天主要在講後端跟JavaScript的部分,加上時間有限,因此沒有太多CSS的修飾,以功能為主的探討。
首先,Controller先將HomeController之外的Controller殺掉,再將HomeController除了index之外的都刪掉;Views的部分將Home跟Shared之外的資料夾刪掉,Home只留下index.cshtml一個檔案就好,其他資料夾不要亂動,刪錯了就準備重新新增一個專案了,index.cshtml的內容也清空,只留下上面@的區塊,並且加上 Layout = null; 表示不載入主版頁面,這樣執行出來就只會是一個空白的網頁,目前的程式碼如下。
@{
ViewBag.Title = "Home Page";
Layout = null;
}
ViewBag.Title目前是用不到了,一般是用來顯示標題用的,不過我也不特別拿掉它。
以下簡單用ViewBag來傳遞三種物件,Model的部分明天會提到,今天雖然有用到但不特別說明了,將程式碼跟網頁顯示出來的結果Show出來供大家參考。
以下是實作的部分:
Controllers/HomeController.cs的內容
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MVCTest.Controllers
{
public class HomeController : Controller
{
public class Student
{
public string id { get; set; }
public string name { get; set; }
public int score { get; set; }
public Student()
{
id = string.Empty;
name = string.Empty;
score = 0;
}
public Student(string _id, string _name, int _score)
{
id = _id;
name = _name;
score = _score;
}
public override string ToString()
{
return $"學號:{id}, 姓名:{name}, 分數:{score}.";
}
}
public ActionResult Index()
{
DateTime date = DateTime.Now;
Student data = new Student();
List<Student> list = new List<Student>();
list.Add(new Student("1", "小明", 80));
list.Add(new Student("2", "小華", 70));
list.Add(new Student("3", "小英", 60));
list.Add(new Student("4", "小李", 50));
list.Add(new Student("5", "小張", 90));
ViewBag.Date = date;
ViewBag.Student = data;
ViewBag.List = list;
return View();
}
}
}
Views/Home/index.cshtml的內容
@{
ViewBag.Title = "Home Page";
Layout = null;
var date = ViewBag.Date;
var student = ViewBag.Student;
var list = ViewBag.List;
}
<style>
div
{
margin-bottom: 10px;
}
</style>
<div>
現在時間: @date.ToString("yyyy/MM/dd HH:mm:ss")
</div>
<div>
學生成績: @student.ToString()
</div>
<div>
學生成績列表:
</div>
@for (int i = 0; i < list.Count; i++)
{
<div>
@list[i].ToString()
</div>
}
網頁顯示的畫面
今天先寫到這邊,
明天主要講解今天的程式內容。
附上今天的參考資料:
[ASP.NET MVC] ASP.NET MVC 傳遞資料容器(一) - ViewData vs ViewBag
--
小弟不才,
如果有謬誤或是要補充的,
都歡迎一起來討論!
補充一下:
ViewBag
雖然返回值是dymanic 但其實也是ViewData
@Model
其實是 ViewData.Model
TempData
可以跨請求原因是把資料存在Session
中,有興趣的可以去MVC原始碼看看SessionStateTempDataProvider
這個類別感謝補充,我再研究看看
為什麼我套用你的程式碼,中文字會產生亂碼呢?
你是用Mac的吧,
Mac我就不知道了,
不過亂碼這種東西跟編碼有關,
你要去看哪裡的編碼出了問題,
我們現在通常用的都是UTF-8.
想請問:return有辦法一次回傳多個值嗎?
$是 VS 2015 之後才可以用的,
你用的應該是舊的版本,
如果沒有特別原因一定要使用舊版本的話,
我蠻推薦使用VS 2015的,
倒是可以以這個版本為主作開發.
return 基本上只能回傳一個object,
如果要回傳多個值,
可以自己寫一個類別(class)來做回傳.
不過還有其他的方式,
如 ref 跟 out,
這部分如果不清楚可以Google一下.
好的!我後來將return全部轉為string並集中到一個變數之中,就成功回傳了,謝謝您!